package ar.edu.uba.fi.jmit.monitorengine.core;

import ar.edu.uba.fi.jmit.integrationcommons.Event;
import ar.edu.uba.fi.jmit.integrationcommons.EventPriority;
import ar.edu.uba.fi.jmit.monitorengine.Constants;
import ar.edu.uba.fi.jmit.monitorengine.MonitorEngineTestCase;
import ar.edu.uba.fi.jmit.monitorengine.ResourceProperties;
import ar.edu.uba.fi.jmit.monitorengine.mock.ConfigurationManagerMock;
import ar.edu.uba.fi.jmit.monitorengine.mock.FrontControllerMock;
import ar.edu.uba.fi.jmit.monitorengine.mock.MockMonitor1;
import ar.edu.uba.fi.jmit.monitorengine.mock.MockMonitor2;

public class FrontControllerTestCase extends MonitorEngineTestCase {
	
	public FrontControllerTestCase() {
		super();
	}
	
	public void setUp() throws Exception {
		super.setUp();
		MockMonitor1.restart();
		MockMonitor2.restart();
		ConfigurationManagerMock.useMockConfigurationManager();
		FrontControllerMock.useFrontControllerMock();
	}

	public void testOnRecivedEventOneMonitor() {
		logger.debug("testOnRecivedEvent");
		FrontController controller = FrontController.getInstance();
		controller.addMonitorDescriptor(getMockMonitorDescriptor(1));
		Event event = getMockMonitorEvent("testMonitor");
		ConfigurationManagerMock.addMonitorType("testMonitor", "eventType1");
		controller.onRecivedEvent(event);
		assertEquals(1, MockMonitor1.getExecutedEvents().size());
		assertEquals(event, MockMonitor1.getExecutedEvents().get(MockMonitor1.getExecutedEvents().size() - 1));
	}
	
	public void testTwoMonitorForSameEvent() {
		logger.debug("testTwoMonitorForSameEvent");
		FrontController controller = FrontController.getInstance();
		controller.addMonitorDescriptor(getMockMonitorDescriptor(1));
		controller.addMonitorDescriptor(getMockMonitorDescriptor(2));
		Event event = getMockMonitorEvent("testMonitor");
		ConfigurationManagerMock.addMonitorType("testMonitor", "eventType1");
		controller.onRecivedEvent(event);
		assertEquals(1, MockMonitor1.getExecutedEvents().size());
		assertEquals(event, MockMonitor1.getExecutedEvents().get(MockMonitor1.getExecutedEvents().size() - 1));
		assertEquals(1, MockMonitor2.getExecutedEvents().size());
		assertEquals(event, MockMonitor2.getExecutedEvents().get(MockMonitor2.getExecutedEvents().size() - 1));
	}
	
	public void testNoMonitorForEvent() {
		logger.debug("testTwoMonitorForSameEvent");
		FrontController controller = FrontController.getInstance();
		controller.addMonitorDescriptor(getMockMonitorDescriptor(1));
		controller.addMonitorDescriptor(getMockMonitorDescriptor(2));
		Event event = getMockMonitorEvent("testMonitor");
		ConfigurationManagerMock.addMonitorType("testMonitor", "eventType2");
		controller.addMonitorDescriptor(getMockMonitorDescriptor(1));
		controller.onRecivedEvent(event);
		assertEquals(0, MockMonitor1.getExecutedEvents().size());
		assertEquals(0, MockMonitor2.getExecutedEvents().size());
	}
	
	public void testOneOfManyMonitors() {
		logger.debug("testTwoMonitorForSameEvent");
		FrontController controller = FrontController.getInstance();
		controller.addMonitorDescriptor(getMockMonitorDescriptor(1, "eventType1"));
		controller.addMonitorDescriptor(getMockMonitorDescriptor(2, "eventType2"));
		Event event = getMockMonitorEvent("testMonitor2");
		ConfigurationManagerMock.addMonitorType("testMonitor1", "eventType1");
		ConfigurationManagerMock.addMonitorType("testMonitor2", "eventType2");
		controller.onRecivedEvent(event);
		assertEquals(0, MockMonitor1.getExecutedEvents().size());
		assertEquals(1, MockMonitor2.getExecutedEvents().size());
		assertEquals(event, MockMonitor2.getExecutedEvents().get(MockMonitor2.getExecutedEvents().size() - 1));
	}

	private MonitorDescriptor getMockMonitorDescriptor(int mockNumber, String eventType) {
		MonitorDescriptor monitorDescriptor = new MonitorDescriptor(
				"ar.edu.uba.fi.jmit.monitorengine.mock.MockMonitor" + mockNumber,
				MonitorLifeType.STATELESS,
				eventType);
		return monitorDescriptor;
	}

	private Event getMockMonitorEvent(String monitorName) {
		Event event = new Event();
		event.setSource("FrontControllerTestCase");
		event.setPriority(EventPriority.NORMAL);
		event.addData(ResourceProperties.getProperty(Constants.EVENT_MONITOR_NAME_KEY), monitorName);
		return event;
	}

	private MonitorDescriptor getMockMonitorDescriptor(int mockNumber) {
		return getMockMonitorDescriptor(mockNumber, "eventType1");
	}

}
